<script setup lang="ts">
import { ref, defineOptions, onMounted, reactive, nextTick } from 'vue'
import { Delete, Edit, Plus } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import {
  type User,
  page,
  count,
  create,
  deleteById,
  updateById,
  deleteByIds
} from '@/api/system/user'
import { putObject } from '@/api/file'
import userImg from '@/assets/images/user1.jpg'
import { getHeightToBottom } from '@/utils/view'
defineOptions({
  name: 'SystemUser'
})
const pageData = ref([] as User[])
const total = ref(0)
const pageSize = ref(10)
const currentPage = ref(1)
const query = ref({} as User)
const tableRef = ref(null)
const tableHeight = ref(360)
const selectData = ref([] as User[])

const dialogType = ref('')
const dialogVisible = ref(false)
const dialogTitle = ref('')
const formRef = ref<FormInstance>()
const entity = ref({} as User)
const rules = reactive<FormRules<User>>({
  nickname: [
    {
      required: true,
      trigger: 'blur',
      validator: (rule, value, callback) => {
        if (!value || !value.trim()) {
          return callback(new Error('请输入昵称'))
        }
        if (value.trim().length < 5) {
          return callback(new Error('请输入长度最少为5位的昵称'))
        }
        callback()
      }
    }
  ],
  username: [
    {
      required: true,
      trigger: 'blur',
      validator: (rule, value, callback) => {
        console.log('username validator', value)
        if (!value || !value.trim()) {
          return callback(new Error('请输入用户名'))
        }
        if (value.trim().length < 5) {
          return callback(new Error('请输入长度最少为5位的用户名'))
        }
        callback()
      }
    }
  ]
})

// 初始化组件后获取页面第一页
onMounted(async () => {
  await initPage()
  heightToBottom()
})

// 动态计算表格高度
const heightToBottom = () => {
  tableHeight.value = getHeightToBottom(tableRef.value) - 70
}

// 重新初始化数据
const initPage = async () => {
  currentPage.value = 1
  const countR = await count(query.value)
  total.value = countR.data
  await handleCurrentChange()
}

const closeQuery = () => {
  query.value = {}
  initPage()
  tableRef.value?.clearSelection()
  tableRef.value?.clearSort()
}

// 分页数量发生变化时
const handleSizeChange = async () => {
  currentPage.value = 1
  const pageR = await page(query.value, currentPage.value, pageSize.value)
  pageData.value = pageR.data
  heightToBottom()
}
// 当前页发生变化时
const handleCurrentChange = async () => {
  const pageR = await page(query.value, currentPage.value, pageSize.value)
  pageData.value = pageR.data
}
// 当勾选发生变化时
const handleSelectionChange = (val: User[]) => {
  selectData.value = val
}
// 当排序发生变化时
const handleSortChange = async (val: SortChange) => {
  query.value.order = val.order
  query.value.prop = val.prop
  await handleCurrentChange()
}
// 打开修改dialog
const dialogEdit = async (info: User) => {
  dialogType.value = 'edit'
  entity.value = info
  dialogTitle.value = `用户详情 - ${entity.value.nickname}`
  dialogVisible.value = true
  nextTick(() => {
    formRef.value.validate()
  })
}
// 打开新增dialog
const dialogAdd = async () => {
  entity.value = {}
  dialogType.value = 'add'
  dialogTitle.value = `新增用户`
  dialogVisible.value = true
  nextTick(() => {
    formRef.value.clearValidate()
  })
}
// 修改接口
const updateEntityById = async (formEl: FormInstance) => {
  formEl.validate(async (valid) => {
    if (valid) {
      const res = await updateById(entity.value)
      if (res.success) {
        dialogVisible.value = false
        handleCurrentChange()
        ElMessage.success('修改失败')
      } else {
        console.log('修改失败:', res.message)
        ElMessage.error('修改失败')
      }
    }
  })
}
// 新增接口
const addEntity = async (formEl: FormInstance) => {
  formEl.validate(async (valid) => {
    if (valid) {
      const r = await create(entity.value)
      if (r.success) {
        dialogVisible.value = false
        ElMessage.success('新增成功')
        await initPage()
      } else {
        ElMessage.error('新增失败')
        console.error('新增失败', r.message)
      }
    }
  })
}

const deleteEntityById = async ({ id, nickname }: User) => {
  ElMessageBox.confirm('你确定要删除删除用户【' + nickname + '】吗?', '删除用户', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    const r = await deleteById(id)
    if (r.success) {
      ElMessage.success('删除成功')
      await initPage()
    } else {
      ElMessage.error('删除失败')
      console.error('删除失败', r.message)
    }
  })
}

const deleteEntityList = async () => {
  if (selectData.value.length === 0) {
    ElMessage.error('请选择要删除的用户')
    return
  }
  ElMessageBox.confirm('确定要删除吗？', '提示', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    const ids = selectData.value.map((item) => item.id)
    const r = await deleteByIds(ids)
    if (r.success) {
      ElMessage.success('删除成功')
      await initPage()
    } else {
      ElMessage.error('删除失败')
      console.error('删除失败', r.message)
    }
  })
}

// 自定义上传函数
const customUpload = async (options: any) => {
  const { file } = options
  const formData = new FormData()
  formData.append('file', file)
  formData.append('path', 'user/avatar/')
  formData.append('contentType', file.type)

  try {
    const response = await putObject(formData)
    // 直接处理成功逻辑，不再调用options.onSuccess以避免触发on-success回调
    if (response.success) {
      entity.value.avatar = response.data
      ElMessage.success('头像上传成功')
    } else {
      ElMessage.error('上传失败：响应数据无效')
    }
  } catch (error) {
    ElMessage.error('头像上传失败')
  }
}
// 文件上传之前
const beforeAvatarUpload = async (file: File) => {
  if (file.size > 1024 * 1024) {
    ElMessage.error('用户头像文件大小不能超过1MB')
    return false
  }
}
</script>

<template>
  <el-card shadow="always">
    <el-form ref="queryRef" :model="query" :inline="true" class="w-full flex items-center">
      <el-form-item label="昵称" class="mb-0!">
        <el-input v-model="query.nickname"></el-input>
      </el-form-item>
      <el-form-item label="用户名" class="mb-0!">
        <el-input v-model="query.username"></el-input>
      </el-form-item>
      <el-form-item class="ml-auto mb-0!">
        <el-button icon="Search" type="primary" @click="initPage"> 查询 </el-button>
        <el-button icon="CircleClose" @click="closeQuery"> 清空 </el-button>
      </el-form-item>
    </el-form>
  </el-card>
  <el-card shadow="always" class="mt-[18px]">
    <el-button type="primary" icon="plus" @click="dialogAdd"> 新增 </el-button>
    <el-button type="danger" icon="Delete" @click="deleteEntityList"> 删除 </el-button>
    <el-table
      ref="tableRef"
      :data="pageData"
      row-key="id"
      border
      :height="tableHeight"
      class="mt-[20px]"
      @selection-change="handleSelectionChange"
      @sort-change="handleSortChange"
    >
      <el-table-column type="selection" width="40" align="center" />
      <el-table-column prop="id" label="ID" width="40" align="center" show-overflow-tooltip />
      <el-table-column prop="username" label="用户名" align="center" show-overflow-tooltip>
        <template #default="{ row }">
          <span class="text-blue-400 cursor-pointer" @click="dialogEdit(row)"
            >{{ row.username }}
          </span>
        </template>
      </el-table-column>
      <el-table-column label="图标" align="center">
        <template #default="{ row }">
          <el-avatar :size="30" :src="row.avatar ? row.avatar : userImg" />
        </template>
      </el-table-column>
      <el-table-column prop="nickname" label="昵称" align="center" show-overflow-tooltip />
      <el-table-column
        prop="createTime"
        label="创建时间"
        sortable
        align="center"
        show-overflow-tooltip
      />
      <el-table-column
        prop="updateTime"
        label="更新时间"
        sortable
        align="center"
        show-overflow-tooltip
      />
      <el-table-column fixed="right" label="操作" min-width="120">
        <template #default="{ row }">
          <el-button type="primary" :icon="Edit" @click="dialogEdit(row)" circle />
          <el-button type="danger" :icon="Delete" circle @click="deleteEntityById(row)" />
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      class="mt-[8px]"
      background
      layout=" prev, pager, next,jumper,->,sizes,total "
      :total="total"
      v-model:page-size="pageSize"
      v-model:current-page="currentPage"
      :page-sizes="[10, 20, 50, 100]"
      @update:page-size="handleSizeChange"
      @update:current-page="handleCurrentChange"
    />
  </el-card>
  <el-dialog v-model="dialogVisible" :title="dialogTitle" width="500px">
    <el-form ref="formRef" :model="entity" :rules="rules" label-width="80px" class="w-[80%]">
      <el-form-item label="用户名" prop="username">
        <el-input
          v-model="entity.username"
          placeholder="请输入用户名"
          :disabled="dialogType === 'edit'"
        ></el-input>
      </el-form-item>
      <el-form-item label="昵称" prop="nickname">
        <el-input v-model="entity.nickname" placeholder="请输入昵称"></el-input>
      </el-form-item>
      <el-form-item label="头像" prop="avatar">
        <el-upload
          class="avatar-uploader"
          :before-upload="beforeAvatarUpload"
          :http-request="customUpload"
          :show-file-list="false"
          name="file"
        >
          <img v-if="entity.avatar" :src="entity.avatar" class="avatar" />
          <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
        </el-upload>
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button v-if="dialogType === 'edit'" type="primary" @click="updateEntityById(formRef)">
          提交
        </el-button>
        <el-button v-if="dialogType === 'add'" type="primary" @click="addEntity(formRef)">
          提交
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<style scoped lang="scss">
.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>
@/api/system/user
